FlutterComponent最佳实践之取色我来实现
点击上方蓝字关注我,知识会给你力量
构建个性化的UI是非常酷的。你的应用程序不需要对每个人都是一样的。一个轻松定制你的应用程序的方法是,从客户资料/封面照片中提取调色板。
它是这样做的。
首先,我们从一个网址上加载图片到byte list中。
imageBytes = (await NetworkAssetBundle(Uri.parse(photo)).load(photo))
.buffer
.asUint8List();
然后,我们导入Image lib,这样我们就可以访问每个像素,而不用担心图像的格式问题。
在下面的方法中,我访问了一个像素mesh,所以我可以从图像的不同部分挑选颜色。
List<Color> extractPixelsColors(Uint8List? bytes) {
List<Color> colors = [];
List<int> values = bytes!.buffer.asUint8List();
imageLib.Image? image = imageLib.decodeImage(values);
List<int?> pixels = [];
int? width = image?.width;
int? height = image?.height;
int xChunk = width! ~/ (noOfPixelsPerAxis + 1);
int yChunk = height! ~/ (noOfPixelsPerAxis + 1);
for (int j = 1; j < noOfPixelsPerAxis + 1; j++) {
for (int i = 1; i < noOfPixelsPerAxis + 1; i++) {
int? pixel = image?.getPixel(xChunk * i, yChunk * j);
pixels.add(pixel);
colors.add(abgrToColor(pixel!));
}
}
return colors;
}
如果noOfPixelsPerAxis是4的话,这个网格看起来就是这样。
在这个例子中,我们将提取16个像素。
好了,现在我们有16种颜色,但我们能用它们做什么呢?我们需要以某种方式对它们进行排序,所以我们可以提取调色板。
现在我们尝试将颜色从浅色到深色排序。我们使用computeLuminance方法,这个方法的计算成本很高,所以我们也许不应该在排序方法中进行计算(对每种颜色进行多次计算),但为了这个例子,这也是可以的。
List<Color> sortColors(List<Color> colors) {
List<Color> sorted = [];
sorted.addAll(colors);
sorted.sort((a, b) => b.computeLuminance().compareTo(a.computeLuminance()));
return sorted;
}
经过分类,我们的颜色看起来像这样。
开始时图像较亮(左上方,结束时图像较暗,右下方)。我把它们显示在一个网格中,所以它们可以很容易地放在屏幕上。
我们不需要调色板中的所有16种颜色,这太多了,所以让我们试着提取4种颜色。
为了做到这一点,我将把这个16种颜色的列表分成4个4种颜色的子列表,在每个子列表中找到平均颜色,这些平均颜色将成为我们最终调色板颜色列表中的项目。
Color getAverageColor(List<Color> colors) {
int r = 0, g = 0, b = 0;
for (int i = 0; i < colors.length; i++) {
r += colors[i].red;
g += colors[i].green;
b += colors[i].blue;
}
r = r ~/ colors.length;
g = g ~/ colors.length;
b = b ~/ colors.length;
return Color.fromRGBO(r, g, b, 1);
}
平均颜色的计算方法是将所有的红色、蓝色和绿色成分加在一起,然后将总和除以所加颜色的数量。
调色板中的第一种颜色(右边没有1)是由排序列表中的前4种颜色(0、1、2、3)组成的,第二种颜色是4、5、6、7,第三种颜色是8、9、10、11,第四种是12、13、14、15。
为了防止用户界面被这些繁重的计算所阻塞,我使用了compute方法,它在一个独立的isolate(具有独立内存的新线程)上执行你的函数,并返回你的结果。
你从图像中提取的像素越多,就会花费更多的时间,所以要找到你要提取的最佳像素数。另外,图像越大,下载和解码的时间就越长。如果你能使用一些缩略图或你知道不是很大的图片,那将是最好的 :) 在下面的视频中,我提取了12x12=144像素,你可以看到它需要一两秒钟。
gif太大 看不了,请点击原文链接查看
原文链接:https://mobileappcircular.com/how-to-extract-a-color-palette-from-an-image-in-flutter-dart-d3d49699a5eb
源码地址:https://github.com/jelenalecic/coloring
向大家推荐下我的网站 https://xuyisheng.top/ 点击原文一键直达
专注 Android-Kotlin-Flutter 欢迎大家访问
往期推荐
更文不易,点个“三连”支持一下👇